/*
 * @Author: lujing
 * @Date: 2024-06-13 09:29:14
 * @LastEditTime: 2024-06-25 11:32:54
 * @FilePath: \workspace\fy\aiDigitalPerson\dipu-xjy-meta-digital-person\src\pages\digitalHuman\Home.tsx
 */
import {  Box, Typography,Button,TextField ,Dialog ,DialogActions ,DialogContent ,DialogContentText ,DialogTitle  } from '@mui/material';
import DigitalBg from 'assets/digital-bg.png'
import Human from 'components/digital/HumanContainer'
import ChatBox from 'components/digital/ChatContainer'
import zantingIcon from 'assets/zanting-active.png';
import pauseIcon from 'assets/pause_02.png';
import {promtStringState, isRenderingState, loadingState, voicingState, sessionState, messagesState, IMessage,openComfirmState,fullscreenState,isLoadingFinishState } from 'state/chat';
import { useRecoilState, useSetRecoilState, useRecoilValue } from 'recoil';
import { useEffect } from 'react';
import { clientState } from 'state/client';
import { v4 as uuidv4 } from 'uuid';
import {digitalIframeUrl123,digitalIframeUrl124,digitalIframeUrl125} from 'api/index';
import { toast } from 'react-hot-toast';
import FullscreenIcon from '@mui/icons-material/Fullscreen';
import fullscreenIcon from 'assets/fullscreen.png'


export default function Home() {
    const queryString = window.location.search;
    const urlParams = new URLSearchParams(queryString);
    const shuziren = urlParams.get('shuziren')=='123'?digitalIframeUrl123:urlParams.get('shuziren')=='124'?digitalIframeUrl124:digitalIframeUrl125;
    const setIsRendering = useSetRecoilState(isRenderingState);
    const setLoading = useSetRecoilState(loadingState);
    const loading = useRecoilValue(loadingState)
    const setVoicing = useSetRecoilState(voicingState);
    const session = useRecoilValue(sessionState);
    const promtString = useRecoilValue(promtStringState);
    const [messages, setMessages] = useRecoilState(messagesState)
 
    let currMessageId ="";//当前正在响应的消息id;

    const handleStopRendering = () => {
        setLoading(false);
        setIsRendering(false);
        // 打断数字人讲话，等待中
        setVoicing('event_vad_end')
        // 触发数字人讲话[停止说话]
        client.setAISay('','task_stop')

    };
    
    const client = useRecoilValue(clientState);
    // 一些临时数据
    let dealResultStr = "";//解析后的字符串集合
    // 监听是否收到声音
    useEffect(()=>{
        if(promtString){
            // 打断上一个问题
            handleStopRendering();
            setTimeout(()=>{
                setIsRendering(true)
                // 展示一条问题
                const message: IMessage = {
                    id: uuidv4(),
                    author: '访客',
                    authorIsUser: true,
                    content: promtString,
                    createdAt: new Date().toISOString()
                };
                // 添加一条消息
                setMessages((m)=>[...m,message])
                setLoading(true)
                getResult(promtString)
            },800)
        }
       
    },[promtString])

    useEffect(()=>{
        // 触发数字人说开场白
        setTimeout(()=>{
            client.setAISay('你好，我是新建元的数字员工元晓宇，请使用"晓宇晓宇"唤醒我进行提问。','stream_token')
            client.setAISay('','stream_end')
        },5000)
    },[])
    async function  getResult(promtString:string){
        // 发起请求之前，清空答案变量；生成一个消息
        dealResultStr = "";
         // 生成一个消息模板
         let  messageId = uuidv4();
         currMessageId = messageId;
         let  message1: IMessage = {
            id: messageId,
            author: '元晓宇',
            authorIsUser: false,
            content: '',
            createdAt: new Date().toISOString()
         };

        // 获取答案：思考中
        setVoicing('event_vad_think')
        let streamController = await client.getLLMData(promtString,(done,token)=>{
            // console.log('一次拉去数据==='+token)
            if(done){
                client.setAISay('','stream_end')
                // stream_start：开始推送数据
                // stream_token：正在推送数据
                // stream_end：推送数据正常结束
                // task_stop：用户打断当前交互流程
                
            }else{
                // 这里很重要，如果已经有新的消息，之前被打断的消息就不要一直生成
                if(currMessageId != messageId){
                    // @ts-ignore
                    streamController&&streamController.close();
                    return;
                }else if(currMessageId == messageId){
                     // 回调一次就要解析一次
                    dealResult(token,messageId,message1);

                }
                
            }
        })
    }
    //1
    const dealResult = (token:string,messageId:string,messageTemplate:IMessage)=>{
            let currResult = ""
            // 从字符串结果中获得对象
            let resultList =  dealStr2Arr(token)
            // 得到正确的答案
            resultList.forEach(item=>{
                if(item.path=='/streamed_output/-'){
                    currResult+=item.value;
                }
            })
            dealResultStr += currResult

            // 每次拉取的数据，有答案内容，就要播报和展示
            if(currResult){
             
              client.setAISay(currResult,'stream_token')
              setMessages((m)=>{
                let oldLastMsg = m[m.length-1];
                    // 此消息已经存在，继续追加内容
                    if(oldLastMsg.id == messageId){
                        // console.log('追加'+dealResultStr)
                        return[...m.slice(0,m.length-1),{...oldLastMsg,content:dealResultStr}]
                    // 需要新创建消息
                    }else{
                        // 如果最后一个消息不是当前正在回答的消息，
                        // 而且当前消息用户的提问,这个时候才追加一个消息
                        if(oldLastMsg.authorIsUser){
                            // console.log('新增'+dealResultStr)
                            let tempMsg = {...messageTemplate,content:dealResultStr}
                            return [...m,tempMsg]

                        }else{
                            return [...m]
                        }
                      
                    }
                    
               
              })
               // 触发数字人讲话：开始讲话
               setVoicing('event_vad_begin')

            }
              
    }

    const  dealStr2Arr = (token:string)=>{
            // 正则表达式匹配
            const regex = /data: (\{(?:[^{}]|(?:\{[^{}]*\}))*\})/g;
            let match;
            const result = [];

            // 循环匹配字符串中的所有对象并存入数组
            while ((match = regex.exec(token)) !== null) {
                const jsonData = match[1];
                try {
                    const parsedData = JSON.parse(jsonData);
                    // 判断是否包含"value"和"path"字段
                    if (parsedData.ops && Array.isArray(parsedData.ops)) {
                    for (const op of parsedData.ops) {
                        if (op.op === "add" && op.path && op.value) {
                        result.push({ path: op.path, value: op.value });
                        }
                    }
                    }
                } catch (error) {
                    debugger;
                    console.error('解析 JSON 出错:', error);
                }
            }

            return result;

    }

    const setPromtString= useSetRecoilState(promtStringState);
 
  
    const onSend1 = ()=>{
        setPromtString('介绍下你自己')
    }
    const onSend2 = ()=>{
        setPromtString('介绍下新建元')

    }
    const onSend3 = ()=>{
        setPromtString('介绍下新建元的资产规模')

    }
    const onSend4 = ()=>{
        setPromtString('新建元有哪些业务')

    }
    const onSend5 = ()=>{
        setPromtString('介绍下新建元数科')

    }
    const onSend6 = ()=>{
        setPromtString('介绍下新建元数科业务布局')
    }

    return (
        <Box id='digitalBoxId' sx={{margin:'0 auto',position:'relative',width:'1080px',height:'100%',overflow:'hidden'}}>
                        <Box sx={{
                            width:'100%',height:'100%',
                            overflow: 'hidden',
                        }}>
                            <div style={{display:'flex',alignItems:'center',justifyContent:'center',position:'absolute',top:'5%',
                            left:'2%',zIndex:'100'}}>
                            <span style={{color:'black',cursor:'pointer',marginLeft:'20px',fontSize:'32px'}} onTouchStart={onSend1} onClick={onSend1}>提问1</span>
                            <span style={{color:'black',cursor:'pointer',marginLeft:'20px',fontSize:'32px'}} onTouchStart={onSend2} onClick={onSend2} >提问2</span>
                            <span style={{color:'black',cursor:'pointer',marginLeft:'20px',fontSize:'32px'}} onTouchStart={onSend3} onClick={onSend3} >提问3</span> 
                            <span style={{color:'black',cursor:'pointer',marginLeft:'20px',fontSize:'32px'}} onTouchStart={onSend4} onClick={onSend4} >提问4</span>
                            <span style={{color:'black',cursor:'pointer',marginLeft:'20px',fontSize:'32px'}} onTouchStart={onSend5} onClick={onSend5} >提问5</span>
                            <span style={{color:'black',cursor:'pointer',marginLeft:'20px',fontSize:'32px'}} onTouchStart={onSend6} onClick={onSend6} >提问6</span>
                            </div>
                        </Box>
                    </Box>   
    );
}
